package ui.model;

import bean.ModelType;
import bean.Score;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import joinery.DataFrame;
import org.jfree.chart.ChartPanel;
import tool.CategoryChartBuilder;
import rxclass.ConcatFunction;
import rxclass.XYObserver;
import tool.Lg;
import tool.StaticProvider;

import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.util.List;

import static tool.TableProperty.SCORE;

public class ChartModel extends BaseModel{
    private Map<String, JPanel> regeistPanel = new HashMap<>();
    private JPanel nowPanel;
    public ChartModel() {
        super(ModelType.Chart);
        this.setLayout(new BorderLayout());

//        showStudentMeanScoreRank();
//        showAClassStudentScoreRank("30000");//展示一个课的学生成绩排名
//        showAStudentScoreComment("200900130002");//展示一个学生的成绩的分类柱状图
//        showClassChoosedCountRank();//展示课程的选择人数的排名
        showStudentAgeCount();//展示学生的年龄
//        showStudentChooseClassCountRank();//展示学生选课数的排名
//        showClassMeanScoreRank();//展示课程平均成绩排名
    }
    private void AddPanel(String func,JPanel jPanel)
    {
        ClearPanel();
        regeistPanel.put(func,jPanel);
        nowPanel = jPanel;
        this.add(jPanel);

    }
    private void ClearPanel()
    {
        if (nowPanel != null)
        {
            this.remove(nowPanel);
            nowPanel = null;
        }
    }

    public void showAStudentScoreComment(String sid)
    {
        final DataFrame<Object> dataFrame = StaticProvider.getInstance().provideAStudentScoreComment(sid);
        final List<List<String>> x = new LinkedList<>();
        final List<Float> y = new LinkedList<>();
        Observable.fromIterable(dataFrame.index())
                .subscribe(new Observer() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Object o) {
                        Float ty = Float.valueOf(dataFrame.get(o, SCORE).toString());
                        List cast = LinkedList.class.cast(o);
                        String s = cast.get(1).toString();
                        String parse = Score.parse(Integer.parseInt(s));
                        cast.set(1,parse);
                        Collections.reverse(cast);
                        x.add(cast);
                        y.add(ty);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {
                        ChartPanel build = CategoryChartBuilder.create().setName("Student Score Star Count")
                                .xyLabel("CLASS", "Count")
                                .geneData(x, y)
                                .setLegend(true)
                                .buildBar();
                        ChartModel.this.add(build);
                        ChartModel.this.revalidate();
                        Lg.info("----");
                    }
                });
    }

    /**
     * 柱状图展示前10个
     * @param cid
     */
    public void showAClassStudentScoreRank(String cid)
    {
        DataFrame<Object> dataFrame = StaticProvider.getInstance().provideAClassStudentScoreRank(cid)
                .tail(10);

        final List<List<String>> x = new LinkedList<>();
        final List<Float> y = new LinkedList<>();

        Observable.just(dataFrame.iterrows())
                .concatMap(new ConcatFunction()).subscribe(new XYObserver() {
            @Override
            public void onNext(List<Object> objects) {
//                Lg.info(objects);
                List list = new LinkedList();
                list.add(objects.get(0));
                list.add(objects.get(1));
                x.add(list);
                y.add(Float.valueOf(objects.get(2).toString()));
            }

            @Override
            public void onComplete() {
                ChartPanel build = CategoryChartBuilder.create().setName("ClassChoosedCountRank")
                        .xyLabel("CLASS", "Count")
                        .setLegend(false)
                        .setBarTick(20)
                        .geneData(x, y)
                        .buildBar();
                ChartModel.this.add(build);
                ChartModel.this.revalidate();
                Lg.info("----");
            }
        });
    }

    /**
     *
     */
    public void showClassChoosedCountRank()
    {
        DataFrame<Object> dataFrame = StaticProvider.getInstance().provideClassChoosedCountRank();
        final List<String> x = new LinkedList<>();
        final List<Float> y = new LinkedList<>();
        Observable.just(dataFrame.iterrows())
                .concatMap(new ConcatFunction()).subscribe(new XYObserver() {
            @Override
            public void onNext(List<Object> objects) {
//                Lg.info(objects);
                x.add(String.valueOf(objects.get(0)));
                y.add(Float.valueOf(objects.get(1).toString()));
            }

            @Override
            public void onComplete() {
                ChartPanel build = CategoryChartBuilder.create().setName("Class Choosed Count Rank")
                        .xyLabel("CLASS", "Count")
                        .geneData(x, y,"default")
                        .buildLine();
                ChartModel.this.add(build);
                ChartModel.this.revalidate();
                Lg.info("----");
            }
        });

    }
    public void showClassMeanScoreRank()
    {
        DataFrame<Object> dataFrame = StaticProvider.getInstance().provideClassMeanScoreRank();
        final List<String> x = new LinkedList<>();
        final List<Float> y = new LinkedList<>();
        Observable.just(dataFrame.iterrows())
                .concatMap(new ConcatFunction()).subscribe(new XYObserver() {
            @Override
            public void onNext(List<Object> objects) {
//                Lg.info(objects);
                x.add(String.valueOf(objects.get(0)));
                y.add(Float.valueOf(objects.get(1).toString()));
            }

            @Override
            public void onComplete() {
                ChartPanel build = CategoryChartBuilder.create().setName("Class Mean Score Rank")
                        .xyLabel("CLASS", "Count")
                        .geneData(x, y,"default")
                        .buildLine();
                ChartModel.this.add(build);
                ChartModel.this.revalidate();
                Lg.info("----");
            }
        });

    }
    public void showStudentChooseClassCountRank()
    {
        DataFrame<Object> dataFrame = StaticProvider.getInstance().provideStudentChooseClassCountRank()
                .tail(20);
        final List<String> x = new LinkedList<>();
        final List<Float> y = new LinkedList<>();
        Lg.info("---");
        Observable.just(dataFrame.iterrows())
                .concatMap(new ConcatFunction()).subscribe(new XYObserver() {
            @Override
            public void onNext(List<Object> objects) {
//                Lg.info(objects);
                x.add(String.valueOf(objects.get(0)));
                y.add(Float.valueOf(objects.get(1).toString()));
            }
            @Override
            public void onComplete() {
                ChartPanel build = CategoryChartBuilder.create().setName("StudentChooseClassCountRank")
                        .xyLabel("SID", "Count")
                        .geneData(x, y,"default")
                        .buildLine();
                ChartModel.this.add(build);
                ChartModel.this.revalidate();
            }
        });
    }

    /**
     * 取前两百条形图展示
     */
    public void showStudentMeanScoreRank()
    {
        DataFrame<Object> dataFrame = StaticProvider.getInstance().provideStudentMeanScoreRank();
        final List<String> x = new LinkedList<>();
        final List<Float> y = new LinkedList<>();
        Lg.info("---");
        Observable.just(dataFrame.iterrows())
                .take(200)
                .concatMap(new ConcatFunction()).subscribe(new XYObserver() {
            @Override
            public void onNext(List<Object> objects) {
//                Lg.info(objects);
                x.add(String.valueOf(objects.get(0)));
                y.add(Float.valueOf(objects.get(1).toString()));
            }
            @Override
            public void onComplete() {
                ChartPanel build = CategoryChartBuilder.create().setName("Students Mean Score Rank")
                        .xyLabel("SID", "Count")
                        .geneData(x, y,"default")
                        .buildLine();
                ChartModel.this.add(build);
                ChartModel.this.revalidate();
            }
        });
    }

    /**
     * 柱状图展示
     */
    public void showStudentAgeCount()
    {
        DataFrame<Object> dataFrame = StaticProvider.getInstance().provideStudentAgeCount();
        final List<String> x = new LinkedList<>();
        final List<Float> y = new LinkedList<>();
        final Map<String, Float> map = new HashMap<>();

        Observable.just(dataFrame.iterrows())
                .concatMap(new ConcatFunction()).subscribe(new XYObserver() {
            @Override
            public void onNext(List<Object> objects) {
                map.put(objects.get(0).toString()+"years old",Float.valueOf(objects.get(1).toString()));
            }
            @Override
            public void onComplete() {
                ChartPanel build = CategoryChartBuilder.create().setName("Students Age")
                        .xyLabel("SID", "Count")
                        .geneData(map)
                        .buildPie();
                ChartModel.this.add(build);
                ChartModel.this.revalidate();
            }
        });
    }
}
